/*
  Program: Mine Mayhem
  File:    times.h
  Date:    July, 1996 to February,   1997,    version 1.00
	   26 October to 3 December,	      version 2.00
	   8 December to 4 January,  2001,    version 2.10
	   15 January,			      version 2.11
	   18 September to 16 December, 2006, version 2.90

  Definitions for record times and statistics.

  Freeware, Copyright 2006 Jason Hood.
*/

#ifndef _times_h
#define _times_h

#include <tws/tabwin.h>
#include <tws/static.h>
#include <tws/edit.h>
#include <tws/checkbox.h>
#include <tws/menu.h>
#include <tws/button.h>

#include "mine.h"
#include "layout.h"
#include "options.h"
#include "custom.h"
#include "radiogrp.h"

extern FONT *FixedFont, *FixedFontBold, *SysFont1, *SysFontBold1;


const unsigned DateLen = 11 + 1,	// "dd-Mmm-yyyy\0"
	       Entries = 10;
const int      Records = 2,		// normal, perimeter
	       Tables  = 3,		// manual, automark, autoopen
	       Options = 5,
	       OCounter = 3,
	       OMarks	= 4,
	       OTrack	= 8,
	       OClear	= 16,
	       OWrap	= 32;

enum { TIME, SPEED, BBBVPS, BBBV, RATING, NoTotals };


// This class holds the ten fastest times & 3BV/s.
class Table
{
friend class TimesWindow;

public:
  Table() { clear(); }
  void clear();

  void	Enter(int bbbv);		// Lost game
  int	Enter(unsigned time, int bbbv); // Check if game is a record
  char* str(int level, int stat, int which = 0) const;
					// Format the statistics as a string

  void	write(FILE* file) const;
  void	read(FILE* file);

  void	save(FILE* file, const char* title, int lev) const;
  void	best(FILE* file, const char* title, int lev) const;
  bool	won()	 const { return (games != 0); }
  bool	played() const { return (gamestotal != 0); }

protected:
  unsigned gamestotal,			// The number of games played
	   bbbvtotal;			// Overall 3BV total
  double   ratingtotal; 		// Overall rating total
  unsigned games,			// The number of games completed
	   one; 			// Games completed in one click
  double   total[NoTotals];		// Various winning totals
  int	   current,			// Current streak (+ve win, -ve loss)
	   longestwins, 		// Longest winning streak
	   longestloss; 		// Longest losing streak
  char	   startdate[DateLen];		// Date of first winning entry

  struct Entry
  {
    void  clear();
    char* str(int level, int score, bool options) const;
					// Format the entry as a string
    unsigned time,			// In milliseconds
	     start,			// Starting condition
	     finish,			// Finishing condition
	     options,			// Counter, Marks, Tracking, Clear, Wrap
	     bbbv;			// Bechtel's Board Benchmark Value
    char     date[DateLen];
  } fastest[2][Entries];		// Time & 3BV/s

  void shift(int which, unsigned from); // Make room for the new entry
  void GetDate(Entry& entry);
  void Stats(int which, unsigned position, unsigned time, unsigned bbbv);
};

typedef Table TTable[Records][Tables];

// This class holds the tables for each level and option.
class Times
{
friend class TimesWindow;

public:
  Times() : head(NULL), prevCustom(NULL) { }
  ~Times();

  bool Check(int level, int bbbv, unsigned time);  // A record for level?
  void Display(int level, int which);	// Display the records for level

  bool Save(const char* filename);
  bool Load(const char* filename, CustomPopupRes& custom);

  void Add(cLayout& lo);		// Add the layout to the list and menu
  bool Delete(cLayout& lo);		// Remove the layout from the list

protected:
  Table* FindTable(int level, bool perimeter = (Start == PERIMETER),
			      bool automark  = isAutoMark,
			      bool autoopen  = isAutoOpen);
  void write(const TTable& table, FILE* file) const;
  void read(TTable& table, FILE* file);

  TTable Beginner, Intermediate, Expert;

  struct CustomTimes
  {
    Layout layout;
    TTable times;
    CustomTimes* next;
  } *head, *prevCustom;
};


// This is the class that does all the displaying.
class TimesWindow : public TabWin
{
public:
  TimesWindow(const Table& table, int level, unsigned highlight = -1);
  ~TimesWindow();

  void Run();

protected:
  void PaintWindow(int x1, int y1, int x2, int y2);

  void Print(const Table& table);

  void cmOK() { ws.StopRunningEvents(); }

  void CheckAutoMark();
  void CheckAutoOpen();

  void RadioLevel(int);

  void cmTable(int = 0);

  void cmClear();
  void cmClearLevel();
  void cmClearGame();
  void cmClearAll();

  void cmSaveBest();

  DECLARE_RESPONSE_TABLE;

  StaticText *header, *fast[Entries], *status;
  RadioGroup *scores, *level;
  CheckBox   *perimeter, *automark, *autoopen;
  TextButton *clear, *clearlevel, *cleargame, *clearall;
  TextButton *save;

  TextButton *ok;

  Layout CustomSave;

  unsigned highlight[2];
  int highlev, highauto;
  int ix, iy;
  int mx, my;
};

#endif
